Part Number Hot Search : 
7060L1 RX301 GMTC8000 74LS05 22152 SII9287 0509S PN8560
Product Description
Full Text Search
 

To Download AN1045 Datasheet File

  If you can't view the Datasheet, Please click here to try to view without PDF Reader .  
 
 


  Datasheet File OCR Text:
  AN1045/0803 1/16 AN1045 application note st7 s/w implementation of i2c bus master by microcontroller division applications team introduction the goal of this application note is to implement an i2c communications software interface for devices which have no i2c peripheral. the software of this application performs i2c master transmitter and master receiver functions. the master chosen here is a st72324 and the slave is an eeprom (m24c08). the program described in this application note is in c language, a program in assembly lan- guage is also available in the software library (see st7 cd rom on internet). 1 characteristics the main characteristics of this i2c software are: n bit addressing n master transmitter/receiver n several data bytes sent and received (3 in this application) n fscl = 62.5 khz n acknowledge management n error management (af) the i2c synchronous communication needs only two signals: scl (serial clock line) and sda (serial data line). the corresponding port pins used are pa7 for scl and pa6 for sda. these two pins are configured as floating input (to have a high level applied on the pin or to re- ceive data) or as output open drain (to have a low level applied on the pin or to output data). please refer to the st7 datasheet for more details about port configuration. 1
2/16 st7 s/w implementation of i2c bus master 1.1 communication speed the communication speed is modifiable by using the function delay(time) which waits for a given time period and then modifies the frequency of scl. here fscl is equal to 62.5 khz. it can be easily reduced by increasing the period between two clock cycles, but this speed is not far from the highest speed you can have (~70 khz). 1.2 start, stop condition and acknowledge generation the start and stop conditions are always generated by the master. in this software, there are no bits to set to generate these conditions like in the real peripheral: you just have to call the corresponding function (i2cm_start() and i2cm_stop()). an acknowledge is sent after an address or a data byte is received. when the master has to receive an acknowledge from the slave, you have to call the function wait_ack() which reads the sda and scl lines to recognize the acknowledge condition (the sda line put at the low state by the one which sends the acknowledge during one clock pulse). and when the master has to send an acknowledge after receiving data from the slave, you have to call the function i2cm_ack(). 2 st7 i2c communication application 2.1 hardware configuration the st7 communication application hardware is composed of a st72324 microcontroller (which has no i2c peripheral) and any slave (an m24c08 eeprom for example). figure 1. st7 / e2prom i2c communication application st72324 i2c vdd vss scl 5v 2x100w sda 2x12kw m24c08 scl sda vss e 2
3/16 st7 s/w implementation of i2c bus master 2.2 initiating a communication to initiate an i2c communication, first a start condition has to be generated and then the se- lected slave address has to be sent, both by the master. here, this action is done by calling the function i2cm_start() followed by the sending of the slave address with the least significant bit correctly set (0:transmission, 1:reception). as the slave here is an eeprom, two addresses have to be sent by the master to the slave: the address of the slave and the address where you want to write or read into the eeprom (refer to section 3: communication frames). 2.3 sending a data byte on the i2c bus to transmit a new data byte from the st72324, the addresses or data bytes previously trans- mitted have to be completed correctly. this previous byte transmission check is done with the reception of an acknowledge condition by the master. if an error is detected (af: acknowledge failure), the af bit of the created i2c_sr2 register is cleared and the transmission is re- started from the start condition. when the previous data transmission is over, the application writes the new data byte to be transmitted. the data to transmit is put on the created i2c_dr register and is sent bit by bit through padr (pa6=sda), msb first. all the data to send to the slave (and the addresses too) are stored in a table. 2.4 receiving a data byte on the i2c bus to receive a new data byte, the previous data byte to receive has to be completed correctly. this byte reception check is done with the sending of an acknowledge condition by the master. an af cant occur on the master side because its the master that sends the acknowl- edge condition. if there is a problem with the reception of this acknowledge, its up to the slave to manage this problem. the frame in this case (master receiver) is: the master after sending the first start condition and the two addresses, has to resend a start condition followed by the address of the eeprom, but this time with the least significant bit at 1 to make the slave understand its waiting for the data (refer to section 3: communication frames). when the master is receiver, after receiving the last data, it has to generate a non acknowl- edge condition to be able to generate the stop condition afterwards. note: there is no need to clear the ack bit to disable acknowledgement before receiving the second last byte or set the stop bit before receiving the last byte (as is necessary in st7 mcus with a dedicated i2c peripheral), because here acknowledgement and stop condition generation is under software control, while in the i2c peripheral it is under hardware control.
4/16 st7 s/w implementation of i2c bus master 3 communication frames the communication protocol between the master and the slave is given in figure 2. for more details, please refer to the st7 datasheet. figure 2. i2c communication protocol 4 flowcharts figure 3. communication application flowchart ack start e2prom @ sub @ ack data 1 ack data 2 ack data n-1 data n stop ack start e2prom @ sub @ ack data 1 ack data n nack stop ack start e2prom @ ack write data from st7 to e2prom read data from e2prom to st7 initiate transmission (start + addresses) end of buffout? yes no send next table data initiate transmission (start+@+start+@lsb=1) stop condition master transmitter master receiver wait for next data to receive last value to receive? no yes ack? yes no ack? yes no ack? no yes ack non ack stop condition
5/16 st7 s/w implementation of i2c bus master figure 4. buffer of transmission structure the buffer of transmission contains the eeprom address, the sub address (the address where you want to write into the eeprom) and then the data to transmit. in this application, a parameter called n allows you to modify the number of data to transmit and then to receive. the number of data is n-1, that means that in this application, as 3 data have to be sent, n=4. the transmission function is based on a double shift: a shift of the count variable to call 8 times the function i2cm_txdata (to send the 8 bits of one data byte) and a shift into the i2cm_txdata function to always send the msb of the data (refer to figure 5). 0 data nb-2 | | | | nb-3 data2 nb-2 data1 nb-1 sub @ nb eeprom @
6/16 st7 s/w implementation of i2c bus master figure 5. flowchart of the transmission function the reception function is also based on a double shift: a shift of the count variable to call 8 times the function i2cm_rxdata (to receive the 8 bits of one data byte) and a shift of a buffer into the i2cm_rxdata function to receive the data bit by bit on the lsb (refer to figure 6). sda configured as output count=1 i2c_dr=buffout[j] shift of count i2cm_txdata count overflows? yes no wait acknowledge ack ok? yes no af=1 end j-- j=ff? no yes j=nb
7/16 st7 s/w implementation of i2c bus master figure 6. flowchart of the reception function rcpt=1 shift of count i2cm_rxdata count overflows? yes no i2cm_tx for addresses transmission count=1 sda configured as input no af? no yes j=ff? no sda configured as output acknowledge buffin[j]=i2c_dr j-- end
8/16 st7 s/w implementation of i2c bus master 5 software the assembly code given below is for guidance only. /**************** (c) 2003 stmicroelectronics ******************************** project : evaluation board - st7 i2c demo system compilers : cosmic and metrowerks module : i2cm_drv.c revision date : 12/06/03 author : micro controller division application team -*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- the software included in this file is for guidance only. stmicroelectronics shall not be held liable for any direct, indirect or consequential damages with respect to any claims arising from use of this software. -*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- description : st7 i2c single master t/r peripheral software driver. -*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- modifications : 27/08/98 - v1.0 - first version (error management:af). 12/06/03 - v1.1 - 1) compatibility with cosmic and metrowerks. 2) generation of non - ack. 3) update for st72324 **************************************************************************/ #pragma no_string_constr #define sda 6 #define scl 7 /* external declarations ***************************************************/ /* list of all the variables defined in another module and used in this one. */ /* model => #include {file_name}.h */ #include "map72324.h" /* declaration of the i2c hw registers.*/ #include "lib_bits.h" /* bit handling macro definitions.*/ #include "variable.h" /* functiondescriptions ************************************************* / /* description of all the functions defined in this module. */
9/16 st7 s/w implementation of i2c bus master /* model => [static] type_name var_name; or #define */ void delay (unsigned char time) { #ifdef __hiware__ asm { nop /* time is stored on the accumulator automatically */ again: dec a /* when the function is called. */ jrne again /* (15+6*time) clock cycles */ } #else #ifdef __csmc__ { _asm ("nop"); _asm("again: dec a"); _asm(" jrne again"); } #endif #endif } /*-------------------------------------------------------------------------- routine name : i2cm_start input/output : none. description : generates i2c-bus start condition. comments : --------------------------------------------------------------------------*/ void i2cm_start (void) { clrbit(paddr,sda); /* configure sda and scl as floating input to have a high state */ clrbit(paddr,scl); delay(10); setbit(paddr,sda); /* configure sda as output open drain to have a low state */ delay(4); /* waits 39 cycles=4.875s at a fcpu=8mhz to keep the high state on scl */ setbit(paddr,scl); /* configure scl as output open drain to have a low state */ delay(6); /* delay to wait after a start */ } /*-------------------------------------------------------------------------- routine name : i2cm_stop
10/16 st7 s/w implementation of i2c bus master input/output : none. description : generates i2c-bus stop condition. comments : --------------------------------------------------------------------------*/ void i2cm_stop (void) { setbit(paddr,sda); /* configure sda and scl as output open drain to have a low state */ setbit(paddr,scl); clrbit(paddr,scl); /* configure scl as floating input to have a high state */ delay(4); /* macro delay with time=4 (4.875 s) */ clrbit(paddr,sda); /* configure sda as floating input to have a high state */ /* delay after the stop did in main.c with wait_1ms() */ } /*-------------------------------------------------------------------------- routine name : wait_ack input/output : none. description : acknowledge received? comments : transfer sequence = data, ack. --------------------------------------------------------------------------*/ void wait_ack (void) { setbit(paddr,scl); /* output open drain to have a low level */ clrbit(paddr,sda); /* floating input, the slave has to pull sda low */ delay(1); if (valbit(padr,sda)) /* test of sda level, if high -> pb */ { setbit(i2c_sr2,af); clrbit(i2c_sr1,ack); return; } delay(2); if (valbit(padr,sda)) /* test of sda level, if high -> pb */ { setbit(i2c_sr2,af); clrbit(i2c_sr1,ack); return; } delay(5); clrbit(paddr,scl); /* start of the generation of 1 clock pulse */ delay(1); if (valbit(padr,sda)) /* test of sda level, if high -> pb */ {
11/16 st7 s/w implementation of i2c bus master setbit(i2c_sr2,af); clrbit(i2c_sr1,ack); return; } delay(1); if (valbit(padr,sda)) /* test of sda level, if high -> pb */ { setbit(i2c_sr2,af); clrbit(i2c_sr1,ack); return; } delay(1); setbit(paddr,scl); /* end of the clock pulse */ setbit(i2c_sr1,ack); delay(1); clrbit (padr,sda); setbit(paddr,sda); /* reconfigure sda as output to proceed at the next transmission */ } /*-------------------------------------------------------------------------- routine name : i2c_nack input/output : none. description : non acknoledge generation from now. comments : transfer sequence = data, nack. --------------------------------------------------------------------------*/ void i2c_nack (void) { clrbit(i2c_sr2,ack); /* non acknoledge when the master is receiver */ setbit(padr,sda); /* the master pulls the sda line high */ setbit(paddr,scl); /* output open drain to have a low level */ delay(10); clrbit(paddr,scl); /* the master generates a clock pulse */ delay(10); setbit(paddr,scl); /* clock pulse complete */ clrbit(padr,sda); /* the master pulls the sda line high */ delay(3); } /*-------------------------------------------------------------------------- routine name : i2cm_init input/output : none. description : i2c peripheral initialisation routine. comments : contains inline assembler instructions in c like mode ! --------------------------------------------------------------------------*/ void i2cm_init (void)
12/16 st7 s/w implementation of i2c bus master { count=0; i2c_sr1=0; i2c_sr2=0; i2c_dr=0; err_status=0; t_count_err=0; r_count_err=0; setbit(i2c_sr1,m_sl); /* master mode: m_sl=1 */ } /*-------------------------------------------------------------------------- routine name : i2cm_txdata input/output : data byte to be transfered(msb first) / none. description : transmits a data bit. comments : transfer sequence = data, ack, ... --------------------------------------------------------------------------*/ void i2cm_txdata (void) { setbit(paddr,scl); /* low level on scl */ if (i2c_sr2) /* check the communication error status */ { err_status++; t_count_err++; if (t_count_err==0) t_count_err++; } else /* if no error */ { if (valbit(i2c_dr,7)) /* send data bit per bit, msb first */ setbit(padr,sda); /* send a one */ else clrbit(padr,sda); /* send a zero */ i2c_dr*=2; clrbit(paddr,scl); /* high state on scl */ delay(10); } } /*-------------------------------------------------------------------------- routine name : i2cm_rxdata input/output : last byte to receive flag (active high) / received data bit. description : receive a data byte. comments : transfer sequence = data, ack, ev7... --------------------------------------------------------------------------*/ void i2cm_rxdata (void)
13/16 st7 s/w implementation of i2c bus master { if (!i2c_sr2) /* no communication error detected */ { buff*=2; /* shift i2c_dr to receive next bit */ #ifdef __hiware__ asm { nop nop nop } #else #ifdef __csmc__ { _asm("nop"); _asm("nop"); _asm("nop"); } #endif #endif clrbit(paddr,scl); /* rise the scl line */ do{ }while(valbit(padr,scl)!=0); /* wait scl at a high state */ if(valbit(padr,sda)) buff|=1; /* the received bit is 1 */ else buff|=0; /* the received bit is 0 */ delay(10); setbit(paddr,scl); /* scl at a low level */ } else r_count_err++; } /*-------------------------------------------------------------------------- routine name : i2c_ack input/output : none. description : send ack to the slave. comments : --------------------------------------------------------------------------*/ void i2c_ack(void) { clrbit(padr,sda); /* the master pulls the sda line low */
14/16 st7 s/w implementation of i2c bus master setbit(paddr,sda); delay(10); clrbit(paddr,scl); /* waits the master takes the control of sda */ delay(10); setbit(paddr,scl); delay(5); clrbit(paddr,sda); /* the master releases the sda line */ setbit(i2c_sr1,ack); /* ack=1: acknowledge sent by the master */ } /*-------------------------------------------------------------------------- routine name : i2cm_tx input/output : send_tab and n, the number of data to transmit (with 2 addresses) / none. description : transmit data buffer. comments : most significant bytes first. --------------------------------------------------------------------------*/ void i2cm_tx (char * buffout,char nb) { setbit(paddr,sda); /* configure sda as an output to send data */ for (j=nb;j!=0xff;j--) { /* 2 addresses and 3 data to send: from x=n downto x=0 */ flag=0; if ((j==(nb-2))&&(valbit(i2c_sr1,rcpt))) { i2cm_start(); /* start condition */ j=nb; /* eeprom @ with the lsb at 1 to send */ flag=1; } count=1; i2c_dr=buffout[j]; if (flag==1) i2c_dr=i2c_dr|1; /* if master receiver, the address to send is a1 */ do { i2cm_txdata(); /* sending of data bit per bit, msb first */ count*=2; }while(count!=0); wait_ack(); /* wait ack from the slave */ if(!valbit(i2c_sr1,ack)) setbit(i2c_sr2,af);
15/16 st7 s/w implementation of i2c bus master if (flag==1) return; /* if master receiver, go back to i2cm_rx() to receive data */ } } /*-------------------------------------------------------------------------- routine name : i2cm_rx input/output : @ reception buffer + n-2 data/ none. description : receive in data buffer via i2c. comments : most significant bytes first. --------------------------------------------------------------------------*/ void i2cm_rx (char *buffin,char nb) { setbit(i2c_sr1,rcpt); /* master in receiver mode */ i2cm_tx(send_tab,nb); /* send the addresses and wait ack */ if (valbit(i2c_sr2,af)) return; /* if af -> go back to main and restart the reception */ for (j=nb-2;j!=0xff;j--) { count=1; buff=0; clrbit(paddr,sda); /* sda as floating input to read data from the eeprom */ do { i2cm_rxdata(); /* read data bit per bit, msb first */ count*=2; }while(count!=0); i2c_dr=buff; setbit(paddr,sda); /* configure sda as output */ if (j==0) i2c_nack(); /* non acknowledge to make the master generate the stop */ else i2c_ack(); /* to acknowledge read data */ buffin[j]=i2c_dr; /* store read data into buffin */ } } /******************* (c) 2003 stmicroelectronics ************ end of file ***/
16/16 st7 s/w implementation of i2c bus master the present note which is for guidance only aims at providing customers with information regarding their products in order for them to save time. as a result, stmicroelectronics shall not be held liable for any direct, indirect or consequential damages with respect to any claims arising from the content of such a note and/or the use made by customers of the information contained herein in connection with their products. information furnished is believed to be accurate and reliable. however, stmicroelectronics assumes no responsibility for the co nsequences of use of such information nor for any infringement of patents or other rights of third parties which may result from its use. no license is granted by implication or otherwise under any patent or patent rights of stmicroelectronics. specifications mentioned in this publicati on are subject to change without notice. this publication supersedes and replaces all information previously supplied. stmicroelectronics prod ucts are not authorized for use as critical components in life support devices or systems without the express written approval of stmicroele ctronics. the st logo is a registered trademark of stmicroelectronics ? 2003 stmicroelectronics - all rights reserved. purchase of i 2 c components by stmicroelectronics conveys a license under the philips i 2 c patent. rights to use these components in an i 2 c system is granted provided that the system conforms to the i 2 c standard specification as defined by philips. stmicroelectronics group of companies australia - brazil - canada - china - finland - france - germany - hong kong - india - israel - italy - japan malaysia - malta - morocco - singapore - spain - sweden - switzerland - united kingdom - u.s.a. http://www.st.com


▲Up To Search▲   

 
Price & Availability of AN1045

All Rights Reserved © IC-ON-LINE 2003 - 2022  

[Add Bookmark] [Contact Us] [Link exchange] [Privacy policy]
Mirror Sites :  [www.datasheet.hk]   [www.maxim4u.com]  [www.ic-on-line.cn] [www.ic-on-line.com] [www.ic-on-line.net] [www.alldatasheet.com.cn] [www.gdcy.com]  [www.gdcy.net]


 . . . . .
  We use cookies to deliver the best possible web experience and assist with our advertising efforts. By continuing to use this site, you consent to the use of cookies. For more information on cookies, please take a look at our Privacy Policy. X